<template>
  <div class="simulation-table">
    <el-row style="text-align: center; margin-top: 30px">
      <div class="el-upload-button">
        <el-button type="primary" size="small" @click="downloadModelHandle">导出模板</el-button>
        <el-button type="primary" size="small" @click="submitUpload" :disabled="submitBtnDisabled">确定导入</el-button>
        <el-button type="primary" size="small" @click="closeUploadHandle">关闭</el-button>
      </div>
      <el-upload
        drag
        class="upload"
        ref="upload"
        name="upfile"
        :data="paramData"
        :action="action"
        :limit="1"
        :auto-upload="false"
        :file-list="fileList"
        :show-file-list="showFileList"
        :before-upload="handleBeforeUpload"
        :on-exceed="handleExceed"
        :on-change="handleFileChange"
        :on-remove="handleRemove"
        :on-success="handleSuccess"
        :on-error="handleError"
      >
        <i class="el-icon-upload" style="margin: 14px 0 14px 0;"></i>
        <div class="el-upload__text">将文件拖到此处，或<em>点击上传</em></div>
        <div class="el-upload__tip">只能上传xls/xlsx文件</div>
      </el-upload>
    </el-row>
    <el-row class="upload-result-div">
      <el-dialog :lock-scroll="true" :visible="resDialogVisible" @close="resDialogVisible = false" :modal="false" center
                 class="res-dialog">
        <el-row class="res-msg">{{ res.msg }}</el-row>
        <el-row class="res-num" v-if="resNumVisible">
          <div class="res-num-text">导入成功条数：{{ res.data.sucNum }}</div>
          <div class="res-num-text">导入失败条数: {{ res.data.errNum }}</div>
        </el-row>
        <el-row v-if="resDetailBtnVisible">
          <em>
            <el-button type="text" class="res-detail-btn" @click="downloadResultExcel">请点击下载导入结果</el-button>
          </em>
        </el-row>
        <el-row class="res-detail" v-if="resDetailVisible" v-html="res.data.detailMsg"></el-row>

        <el-row style="display: none;">
          <table id="resDetailTable">
            <thead>
            <tr>
              <th width='200px'>行序号</th>
              <th width='300px'>主键</th>
              <th width='500px'>处理结果</th>
            </tr>
            </thead>
            <tbody v-html="resDetailTableHtml">
            </tbody>
          </table>
        </el-row>

      </el-dialog>
    </el-row>
  </div>
</template>
<script>
  import FileSaver from 'file-saver'
  import XLSX from 'xlsx'

  export default {
    name: 'batchOperation',
    // 用来接收父组件传给子组件的数据
    props: {
      // 上传路径，必传
      action: {
        type: String,
        required: true
      },
      // 是否展示选择的文件
      showFileList: {
        type: Boolean,
        default: true
      },
      // 是否开启操作结果（成功/失败条数）的展示
      openResNumVisible: {
        type: Boolean,
        default: false
      },
      // 是否开启操作结果的下载按钮
      openResDetailBtnVisible: {
        type: Boolean,
        default: false
      },
      // 模板下载按钮的事件操作，必传
      downloadModel: {
        type: Function,
        required: true
      },
      // 关闭按钮的事件操作，必传
      closeUpload: {
        type: Function,
        required: true
      }
    },
    data () {
      return {
        fileList: [],
        paramData: {},

        resNumVisible: false,
        resDetailBtnVisible: false,
        resDetailVisible: false,
        resDialogVisible: false,
        res: {msg: '', result: '', data: {}},
        resDetailTableHtml: ''
      }
    },
    computed: {
      submitBtnDisabled: function () {
        if (!this.fileList || this.fileList.length <= 0) {
          return true
        }
        var file = this.fileList[0]
        if (file.status !== 'ready') {
          return true
        }
        return false
      }
    },
    methods: {
      handleBeforeUpload () {
        var result = false

        var fileName = this.paramData.fileName || ''
        var fileList = this.fileList

        var suffix = fileName.split('.')[fileName.split('.').length - 1]  // 后缀
        var fileRealName = fileName.substring(fileName.lastIndexOf('\\') + 1, fileName.lastIndexOf('.'))// 文件名
        suffix = suffix.toLowerCase()

        if (!fileName || fileList.length <= 0) {
          this.$message.info('上传文件不能为空,请选择后上传！')
        } else if (suffix !== 'xls' && suffix !== 'xlsx') {
          this.$message.info('文件类型错误.请重新选择！')
        } else if (fileRealName.replace(/[^\x00-\xff]/g, '**').length > 30) { // 检验文件名的长度
          this.$message.info('上传文件名过长,请修改后上传！')
        } else {
          result = true
        }

        var fileSize = fileList[0].size
        if (fileSize > 10 * 1024 * 1024) {
          this.$message.info('导入文件大小不能大于10M')
          result = false
        }

        return result
      },
      handleExceed (files, fileList) {
        // 防止使用拖拉方式时，拖拉多个文件文件
        if (files.length > 1 || fileList.length > 1) {
          this.$message.info('只能单文件上传!请重新选择')
        }
        // 拖拉多个文件时，不做处理
        if (files.length > 1) {
          return
        }

        for (var i = 0, len = fileList.length; i < len; i++) {
          this.$refs.upload.handleRemove(fileList[i])
        }
        this.$refs.upload.$children[0].uploadFiles(files)
      },
      handleRemove () {
        // 数组清空
        this.fileList = []
      },
      handleSuccess (res, file, fileList) {
        if (!res) {
          this.$message.info('数据请求错误')
        }

        var resData = {}
        if (res.resData) {
          resData = JSON.parse(res.resData)
        }

        if (!resData.detailMsg) {
          resData.detailMsg = this.createResDetailByItems(resData.items)
        }

        this.res.msg = res.msg
        this.res.result = res.result
        this.res.data = resData
        this.resDetailTableHtml = this.createResTableByItems(resData.items)
        this.resDialogVisible = true
        this.resNumVisible = (this.openResNumVisible && resData.sumNum && resData.sumNum > 0)
        this.resDetailVisible = Boolean(resData.detailMsg).valueOf()
        this.resDetailBtnVisible = Boolean(this.openResDetailBtnVisible && this.resDetailTableHtml).valueOf()
      },
      handleError (err, file, fileList) {
        console.log(err)
      },
      handleFileChange (file) {
        if (file && file.status === 'ready') {
          this.paramData.fileName = file.name
          this.fileList = [file]
        }
      },
      downloadModelHandle () {
        this.downloadModel()
      },
      closeUploadHandle () {
        this.closeUpload()
      },
      submitUpload () {
        this.$refs.upload.submit()
      },
      createResDetailByItems (items) {
        var detailMsg = ''
        if (items && items.length > 0) {
          for (var i = 0; i < items.length; i++) {
            var item = items[i]
            if (item.result) {
              continue
            }
            if (!item.index && !item.key) {
              continue
            }
            detailMsg += '第' + item.index + '行：'
            if (item.key) {
              detailMsg += '<b>' + item.key + '</b>'
            }
            detailMsg += item.msg + '!</br>'
          }
        }
        return detailMsg
      },
      createResTableByItems (items) {
        var tableHtml = ''
        if (items && items.length > 0) {
          for (var i = 0; i < items.length; i++) {
            var item = items[i]
            if (item.index || item.key || item.msg) {
              tableHtml += '<tr>'
              tableHtml += '<td>' + item.index + '</td>'
              tableHtml += '<td>' + item.key + '</td>'
              tableHtml += '<td>' + item.msg + '</td>'
              tableHtml += '</tr>'
            }
          }
        }
        return tableHtml
      },
      downloadResultExcel () {
        let wb = XLSX.utils.table_to_book(document.querySelector('#resDetailTable'))
        /* get binary string as output */
        let wbout = XLSX.write(wb, {bookType: 'xlsx', bookSST: true, type: 'array'})
        try {
          FileSaver.saveAs(new Blob([wbout], {type: 'application/octet-stream'}), '导入批量操作错误列表.xlsx')
        } catch (e) {
          if (typeof console !== 'undefined') {
            console.log(e, wbout)
          }
        }
        return wbout
      }

    }
  }
</script>

<style>
  .el-upload-button {
    margin-top: 136px;
    z-index: 8013;
    position: absolute;
    left: 50%;
    transform: translate(-50%);
  }

  .upload-result-div {
    z-index: 8014;
  }

  .res-dialog .el-dialog.el-dialog--center {
    border-radius: 2px;
    box-shadow: -0.1px -0.1px 5px 6px rgba(0, 0, 0, .3);
    box-sizing: border-box;
    width: 430px;
    min-height: 250px;
  }

  .upload .el-upload-list.el-upload-list--text {
    width: 360px;
    position: relative;
    left: 50%;
    transform: translate(-50%);
  }

  .res-msg {
    font-size: 16px;
    font-weight: bold;
    margin-bottom: 5px;
  }

  .res-num {
    margin-bottom: 8px;
  }

  .res-detail-btn {
    padding: 0;
    margin-bottom: 8px;
  }

  .res-detail {
    max-height: 200px;
    height: auto;
    overflow-y: auto;
  }

</style>
